#include "XBOXController.h"

CXBOXController::CXBOXController(int playerNumber)
{
	// Set the Controller Number
	_controllerNum = playerNumber - 1;
}

XINPUT_STATE CXBOXController::GetState()
{
	// Zeroise the state
	ZeroMemory(&_controllerState, sizeof(XINPUT_STATE));

	// Get the state
	XInputGetState(_controllerNum, &_controllerState);

	return _controllerState;
}

bool CXBOXController::IsConnected()
{
	// Zeroise the state
	ZeroMemory(&_controllerState, sizeof(XINPUT_STATE));

	// Get the state
	DWORD Result = XInputGetState(_controllerNum, &_controllerState);

	if(Result == ERROR_SUCCESS)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void CXBOXController::Vibrate(int leftVal, int rightVal)
{
	// Create a Vibraton State
	XINPUT_VIBRATION Vibration;

	// Zeroise the Vibration
	ZeroMemory(&Vibration, sizeof(XINPUT_VIBRATION));

	// Set the Vibration Values
	Vibration.wLeftMotorSpeed = leftVal;
	Vibration.wRightMotorSpeed = rightVal;

	// Vibrate the controller
	XInputSetState(_controllerNum, &Vibration);
}

bool CXBOXController::Convert(KGamePadState& outState)
{
	if (!IsConnected())
		return false;
	
	outState.Clear();
	XINPUT_STATE state = GetState();

	// Button states
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_A)
		outState.button_states |= KGamePadState::eButton_A;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_B)
		outState.button_states |= KGamePadState::eButton_B;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_X)
		outState.button_states |= KGamePadState::eButton_X;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)
		outState.button_states |= KGamePadState::eButton_Y;

	// D-pad states
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
		outState.button_states |= KGamePadState::eDPad_Up;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
		outState.button_states |= KGamePadState::eDPad_Down;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
		outState.button_states |= KGamePadState::eDPad_Left;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
		outState.button_states |= KGamePadState::eDPad_Right;

	// Others
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_START)
		outState.button_states |= KGamePadState::eStart;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)
		outState.button_states |= KGamePadState::eL1;
	if (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
		outState.button_states |= KGamePadState::eR1;

	// Left analog inputs
	{
		float LX = state.Gamepad.sThumbLX;
		float LY = state.Gamepad.sThumbLY;
		float magnitude = sqrt(LX*LX + LY*LY);
		float normalizedLX = LX / magnitude;
		float normalizedLY = LY / magnitude;
		float normalizedMagnitude = 0;

		if (magnitude > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE){
			if (magnitude > 32767) magnitude = 32767;
			magnitude -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
			normalizedMagnitude = magnitude / (32767 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
		}
		else {
			magnitude = 0.0;
			normalizedMagnitude = 0.0;
		}
		outState.analogAxis0[0] = normalizedLX * normalizedMagnitude;
		outState.analogAxis0[1] = normalizedLY * normalizedMagnitude;
	}

	// Right analog inputs
	{
		float RX = state.Gamepad.sThumbRX;
		float RY = state.Gamepad.sThumbRY;
		float magnitude = sqrt(RX*RX + RY*RY);
		float normalizedRX = RX / magnitude;
		float normalizedRY = RY / magnitude;
		float normalizedMagnitude = 0;

		if (magnitude > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE){
			if (magnitude > 32767) magnitude = 32767;
			magnitude -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
			normalizedMagnitude = magnitude / (32767 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
		}
		else {
			magnitude = 0.0;
			normalizedMagnitude = 0.0;
		}
		outState.analogAxis1[0] = normalizedRX * normalizedMagnitude;
		outState.analogAxis1[1] = normalizedRY * normalizedMagnitude;
	}
	return true;
}